import { observable, action } from 'mobx';
import apiService from '../services/api.service';
import { AxiosResponse } from 'axios';
import { LoginViewModel, ResultViewModel, RefreshTokenViewModel, CheckUserViewModel } from '../models/interfaces';

export default class AuthStore {
	@observable isAuth = false;
	@observable username = '';
	@observable roles = '';
	@observable accessToken = '';
	@observable refreshToken = '';

	@action
	init() {
		this.username = '';
		this.accessToken = '';
		this.refreshToken = '';
		this.roles = '';
		this.isAuth = false;

		localStorage.removeItem('accessToken');
		localStorage.removeItem('refreshToken');
	}

	@action
	setLogin(username: string, roles: string) {
		this.username = username;
		this.roles = roles;
		this.isAuth = true;

		localStorage.setItem('accessToken', this.accessToken);
		localStorage.setItem('refreshToken', this.refreshToken);
	}

	@action
	setToken(accessToken: string, refreshToken: string) {
		this.accessToken = accessToken;
		this.refreshToken = refreshToken;
	}

	@action
	async loginAsync(username: string, password: string) {
		const response = await apiService.post<any, AxiosResponse<ResultViewModel<LoginViewModel>>>('Auth/Login', {
			username,
			password
		});
		if (response != null && response.data.code === 0) {
			this.setToken(
				(this.accessToken = response.data.msg.access_token),
				(this.refreshToken = response.data.msg.refresh_token)
			);
			await this.checkUserAsync();
		}
	}

	@action
	async checkUserAsync() {
		const accessToken = localStorage.getItem('accessToken');
		const refreshToken = localStorage.getItem('refreshToken');
		if (accessToken && refreshToken) {
			this.setToken(accessToken, refreshToken);
		}

		if (this.accessToken.length > 0 && this.refreshToken.length > 0) {
			const response = await apiService.get<any, AxiosResponse<ResultViewModel<CheckUserViewModel>>>(
				'/Auth/CheckUser'
			);
			if (response != null && response.data.code === 0) {
				this.setLogin(response.data.msg.username, response.data.msg.roles);
			}
		}
	}

	@action
	async RefreshTokenAsync() {
		const response = await apiService.get<
			any,
			AxiosResponse<ResultViewModel<RefreshTokenViewModel>>
		>('Auth/RefreshToken', {
			params: {
				token: this.refreshToken
			}
		});
		if (response != null && response.data.code === 0) {
			this.setToken(
				(this.accessToken = response.data.msg.access_token),
				(this.refreshToken = response.data.msg.refresh_token)
			);
			await this.checkUserAsync();
		}
	}

	@action
	async logoutAsync() {
		this.init();
	}
}
